
#include "mpi_lib.h"
#include "mpi.h"
#include "mpi_cmd.h"




static u16 vout_a_bt656_para[15][6] =
{
//interlace  H_active_start  H_active_end    V_Active_Start    V_Active_End       V_end
    {    0,          720,                2639,           41,         1120,           1124  },//not fixed format--1080p25
    {    1,          276,                1715,           21,         260,            262   },//480I60
    {    0,          138,                857,            41,         520,            524   },//480P60   OK at un-fixed format 27MHz OK
    {    1,          288,                1727,           22,         309,            312   },//576I50
    {    0,          144,                863,            44,         619,            624   },//576P50   OK at fixed format   27MHz  OK
    {    0,          370,                1649,           25,         744,            749   },//720P60   OK 37.125MHz OK
    {    0,          700,                1979,           25,         744,            749   },//720P50   OK 37.125MHz OK
    {    1,          280,                2199,           20,         559,            561   },//1080I60
    {    1,          720,                2639,           20,         559,            561   },//1080I50
    {    1,          830,                2749,           20,         559,            561   },//1080I48
    {    0,          720,                2639,           41,         1120,           1124  },//not fixed format--1080p25
//{    0,          280,                2199,           41,         1120,           1124  },//not fixed format--1080p30
    {    0,          280,                2199,           41,         1120,           1124  },//not fixed format--1080p30
    {    0,          2680,               3959,           25,         744,            749   },//not fixed format--720p25   74.25MHz
//{    0,          700,               1979,           25,         744,            749   },//not fixed format--720p25          37.125MHz
    {    0,          2020,               3299,           25,         744,            749   },//not fixed format--720p30@74.124   720p15@37.125
    {	 0, 		 138,				 857,			 41,		 520,			 524   },//480P60	OK at un-fixed format 27MHz OK
};


int sgks_mpi_vo_OpenDeviceNode(sgks_mpi_vo_device_s *vo_device, u32 *vo_handle)
{
    CHECK_POINT_NULL_RETURN(vo_device,SGKS_FAIL);

    int ret = 0;
    int i = 0;

    for (i=0; i<vo_device->vo_device_num; i++)
    {
        if((ret = open(vo_device->vo_deviceinfo[i].device_node, O_RDWR, 0)) < 0)
        {
            Printf("err open mpi vo driver dev:%s\n", vo_device->vo_deviceinfo[i].device_node);
            return SGKS_ERR_SYS_OPENDRIVERDEVERR;
        }

        vo_handle[i] = ret;
    }

    return SGKS_SUCCESS;

}


static int sgks_mpi_vo_set_video_size(sgks_vo_dev_info_s *pinfo, sgks_vo_window_info_s *args)
{

    pinfo->video_setup.win_offset_x  = args->start_x;
    pinfo->video_setup.win_offset_y  = args->start_y;
    pinfo->video_setup.win_width     = args->end_x - args->start_x + 1;
    pinfo->video_setup.win_height    = args->end_y - args->start_y + 1;

    return SGKS_SUCCESS;
}



static int sgks_mpi_vo_set_active_win(sgks_vo_dev_info_s *pinfo, sgks_vo_window_info_s *args)
{
    int ret = 0;
    if(pinfo->status == SGKS_VIDEO_SOURCE_STATUS_IDLE)
    {
        pinfo->mixer_setup.act_win_width 						 = args->width;
        pinfo->mixer_setup.act_win_height 						 = args->end_y - args->start_y + 1;
        pinfo->dram_display.d_active_region_start_0.s.startcol  = args->start_x;
        pinfo->dram_display.d_active_region_end_0.s.endcol      = args->end_x;
        pinfo->dram_display.d_active_region_start_0.s.startrow  = args->start_y;
        pinfo->dram_display.d_active_region_end_0.s.endrow      = args->end_y;
        pinfo->dram_display.d_active_region_start_1.s.startcol  = args->start_x;
        pinfo->dram_display.d_active_region_end_1.s.endcol      = args->end_x;

        if(!args->field_reverse)
        {
            pinfo->dram_display.d_active_region_start_1.s.startrow = args->start_y + 1;
            pinfo->dram_display.d_active_region_end_1.s.endrow     = args->end_y + 1;
        }
        else
        {
            pinfo->dram_display.d_active_region_start_1.s.startrow = args->start_y - 1;
            pinfo->dram_display.d_active_region_end_1.s.endrow     = args->end_y - 1;
        }
    }
    else
    {
        ret = -1;
        Printf("%s wrong status %d!\n", __func__, pinfo->status);
    }

    return ret;

}

static int sgks_mpi_vo_conv_active_win(sgks_vo_deviceInfo_s *vout_Device, u32 *sx, u32 *ex,  u32 *sy, u32 *ey, u32 *fr)
{
    int ret = 0;

    switch(vout_Device->mode)
    {
    case SGKS_VO_MODE_WVGA:
        *sx = 21;
        *ex = 1620;
        *sy = 0;
        *ey = 479;
        *fr = 0;
        break;

    case SGKS_VO_MODE_480_854:
        *sx = 51;
        *ex = 1010;
        *sy = 0;
        *ey = 853;
        *fr = 0;
        break;

    case SGKS_VO_MODE_1920_480:
        *sx = 1;
        *ex = 3840;
        *sy = 0;
        *ey = 479;
        *fr = 0;
        break;

    case SGKS_VO_MODE_1280_320:
        *sx = 1;
        *ex = 2560;
        *sy = 0;
        *ey = 319;
        *fr = 0;
        break;

    case SGKS_VO_MODE_1280_272:
        *sx = 1;
        *ex = 2560;
        *sy = 0;
        *ey = 271;
        *fr = 0;
        break;

    case SGKS_VO_MODE_720P30:
        *sx = 21;
        *ex = 2580;
        *sy = 0;
        *ey = 719;
        *fr = 0;
        break;

    case SGKS_VO_MODE_480_1280:
        *sx = 1;
        *ex = 960;
        *sy = 0;
        *ey = 1279;
        *fr = 0;
        break;

    case SGKS_VO_MODE_400_1280:
        *sx = 1;
        *ex = 800;
        *sy = 0;
        *ey = 1279;
        *fr = 0;
        break;


    default:
        Printf("(%d)  mode not support\n", vout_Device->mode);
        ret = -1;
        break;

    }

    return ret;

}

static int sgks_mpi_vo_get_setup(sgks_vo_dev_info_s *pinfo, sgks_dsp_cmd_vo_video_setup_s *args)
{

    memcpy(args, &pinfo->video_setup, sizeof(sgks_dsp_cmd_vo_video_setup_s));

    return SGKS_SUCCESS;

}

int sgks_mpi_vo_MmapPhyAddr(sgks_mpi_manager_s *mpi)
{
    u8 *msg_buf = NULL;
    SGKS_MDI_DRV_BUFF(msg_buf);
    sgks_mdi_mmap_s *mmap_info = msg_buf;

    SGKS_MDI_DRV_CLEAN_DATABUFF();
    mmap_info->mmap_phy_start_addr = (u8 *)mpi->mpi_vo_dev[0].vo_user_param.disp_bank_phy;
    mmap_info->mmap_phy_size       = (int)mpi->mpi_vo_dev[0].vo_user_param.disp_bank_size;
    SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_MMAP, 0, sizeof(sgks_mdi_mmap_s), SGKS_ERR_SYS_DRIVERIOCTLERR);
    mpi->mpi_vo_dev[0].vo_user_param.disp_bank_vir  = (u8 *)mmap_info->mmap_user_start_addr;
	//Printf("vo map: phy addr ----> phy 0x%x  size 0x%x\n",(u8 *)mpi->mpi_vo_dev[0].vo_user_param.disp_bank_phy,(int)mpi->mpi_vo_dev[0].vo_user_param.disp_bank_size);
	//Printf("vo map: phy addr 0x%x ----> vir 0x%x  size 0x%x\n",mmap_info->mmap_phy_start_addr,mmap_info->mmap_user_start_addr, mmap_info->mmap_user_size);

	return SGKS_SUCCESS;
}

int sgks_mpi_vo_YuvMmapPhyAddr()
{
    int ret = -1;

    sgks_mpi_manager_s *mpi = mpi_get_managerHanle();

    ret = sgks_mpi_vo_MmapPhyAddr(mpi);
    if (ret != SGKS_SUCCESS)
    {
        return ret;
    }

    return SGKS_SUCCESS;
}

int sgks_mpi_vo_GetFreeBank(sgks_mpi_vo_DisBankParams_s *vobankparams)
{
	sgks_mpi_manager_s *mpi = mpi_get_managerHanle();

    unsigned long newest_bank, displaying_bank, next_bank;
    static unsigned long *pnewest_bank, *pdisplaying_bank;
    unsigned int baseaddr;

	pnewest_bank = (unsigned long *)mpi->mpi_vo_dev[0].vo_user_param.disp_bank_vir;
    pdisplaying_bank = (unsigned long *)(mpi->mpi_vo_dev[0].vo_user_param.disp_bank_vir + 4);

    displaying_bank = *pdisplaying_bank % 3;

    newest_bank = ((*pnewest_bank + 1) & 0x0000FFFF) % 3;

    if(newest_bank != displaying_bank)
    {
        next_bank = newest_bank;
    }
    else
    {
        next_bank = (newest_bank + 1) % 3;
    }

    *pnewest_bank = (*pnewest_bank & 0x0000FFFF) | (next_bank << 16) | 0xFF000000;

    vobankparams->banknum = next_bank;

    if(mpi->mpi_vo_dev[0].default_img_setup.mjpeg_yuv == 1)
    {
        vobankparams->banksize = mpi->mpi_vo_dev[0].default_img_setup.default_img_pitch * mpi->mpi_vo_dev[0].default_img_setup.mjpeg_height * 2;
    }
    else
    {
        vobankparams->banksize = mpi->mpi_vo_dev[0].default_img_setup.default_img_pitch * mpi->mpi_vo_dev[0].default_img_setup.mjpeg_height / 2 * 3;
    }
	
    baseaddr = (u32)mpi->mpi_vo_dev[0].vo_user_param.disp_bank_vir + 8;
    baseaddr = baseaddr & (64 - 1) ? ((baseaddr & 0xFFFFFFC0) + 64) : baseaddr;
    vobankparams->bankaddr =  (u32 *)(baseaddr + next_bank * vobankparams->banksize);
}

int sgks_mpi_vo_UpdateBank(u32 banknum)
{

	u8 *msg_buf = NULL;
    unsigned int banksize;
	
	sgks_mpi_manager_s *mpi = mpi_get_managerHanle();
	u32 *pnewest_bank = (u32 *)mpi->mpi_vo_dev[0].vo_user_param.disp_bank_vir;
	*pnewest_bank=banknum;

	SGKS_MDI_DRV_BUFF(msg_buf);
	sgks_mdi_opt_d_cache_s *cache			= msg_buf;
	cache->cache_type						= SGKS_OPT_D_CACHE_CLAEN;											  
	cache->start							= mpi->mpi_vo_dev[0].vo_user_param.disp_bank_phy;
	cache->size 							= mpi->mpi_vo_dev[0].vo_user_param.disp_bank_size;
	SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_OPT_D_CACHE, 0, sizeof(sgks_mdi_opt_d_cache_s), SGKS_ERR_SYS_DRIVERIOCTLERR);
	
	
}

static int sgks_mpi_vo_set_setup(sgks_vo_dev_info_s *pinfo, sgks_dsp_cmd_vo_video_setup_s *args)
{
    pinfo->video_setup.en  						= args->en;
    pinfo->video_setup.src 						= args->src;
    pinfo->video_setup.flip 					= args->flip;
    pinfo->video_setup.rotate 					= args->rotate;
    pinfo->video_setup.win_offset_x 			= args->win_offset_x;
    pinfo->video_setup.win_offset_y 			= args->win_offset_y;
    pinfo->video_setup.win_width 				= args->win_width;
    pinfo->video_setup.win_height 				= args->win_height;
    pinfo->video_setup.default_img_y_addr 		= args->default_img_y_addr;
    pinfo->video_setup.default_img_uv_addr 		= args->default_img_uv_addr;
    pinfo->video_setup.default_img_pitch 		= args->default_img_pitch;
    pinfo->video_setup.default_img_repeat_field = args->default_img_repeat_field;

    pinfo->mixer_setup.act_win_width =  pinfo->video_setup.win_width;
    pinfo->mixer_setup.act_win_height =  pinfo->video_setup.win_height;
    return SGKS_SUCCESS;

}


static int sgks_vo_set_osd(sgks_vo_dev_info_s *pinfo,  sgks_dsp_cmd_vo_osd_setup_s *args)
{

    pinfo->osd_setup.en 						= args->en;
    pinfo->osd_setup.src 						= args->src;
    pinfo->osd_setup.flip 						= args->flip;
    pinfo->osd_setup.rescaler_en 				= args->rescaler_en;
    pinfo->osd_setup.premultiplied 				= args->premultiplied;
    pinfo->osd_setup.global_blend 				= args->global_blend;
    pinfo->osd_setup.win_offset_x 				= args->win_offset_x;
    pinfo->osd_setup.win_offset_y 				= args->win_offset_y;
    pinfo->osd_setup.win_width 					= args->win_width;
    pinfo->osd_setup.win_height 				= args->win_height;
    pinfo->osd_setup.rescaler_input_width  		= args->rescaler_input_width;
    pinfo->osd_setup.rescaler_input_height 		= args->rescaler_input_height;
    pinfo->osd_setup.osd_buf_dram_addr 			= args->osd_buf_dram_addr;
    pinfo->osd_setup.osd_buf_pitch 				= args->osd_buf_pitch;
    pinfo->osd_setup.osd_buf_repeat_field 		= args->osd_buf_repeat_field;
    pinfo->osd_setup.osd_direct_mode 			= args->osd_direct_mode;
    pinfo->osd_setup.osd_transparent_color 		= args->osd_transparent_color;
    pinfo->osd_setup.osd_transparent_color_en 	= args->osd_transparent_color_en;
    pinfo->osd_setup_flag 						= SGKS_VO_SETUP_NEW;
    pinfo->osd_clut_setup_flag 					= SGKS_VO_SETUP_NA;
	
    return SGKS_SUCCESS;
	
}



static int sgks_mpi_vo_select_display_input(sgks_vo_dev_info_s *pinfo, sgks_vo_display_input_e args)
{
    int                    errorCode = 0;
    pinfo->dram_display.d_input_stream_enable.s.input_select = args;
    return errorCode;
}


static int sgks_vo_set_bg_color(sgks_vo_dev_info_s *pinfo, sgks_vo_bg_color_info_s *args)
{
    int                    errorCode = 0;

    if (pinfo->status == SGKS_VIDEO_SOURCE_STATUS_IDLE)
    {
        pinfo->dram_display.d_background.s.cr   = args->cr;
        pinfo->dram_display.d_background.s.cb   = args->cb;
        pinfo->dram_display.d_background.s.y  	 = (args->y > 10) ? args->y : 10;
        pinfo->mixer_setup.back_ground_v        = pinfo->dram_display.d_background.s.cr;
        pinfo->mixer_setup.back_ground_u        = pinfo->dram_display.d_background.s.cb;
        pinfo->mixer_setup.back_ground_y        = pinfo->dram_display.d_background.s.y;
    }
    else
    {
        errorCode = -1;
        Printf("%s wrong status %d!\n", __func__, pinfo->status);
    }

    return errorCode;

}


static int sgks_voutA_run(sgks_vo_dev_info_s *pinfo)
{
    int                    errorCode = 0;


    if(pinfo->status == SGKS_VIDEO_SOURCE_STATUS_IDLE)
    {
        pinfo->status = SGKS_VIDEO_SOURCE_STATUS_RUNNING;
        Printf("%s: switch to %d!\n", __func__, pinfo->status);
    }
    else
    {
        Printf("%s already running %d!\n", __func__, pinfo->status);
    }

    return errorCode;
}




static int sgks_mpi_vo_UpdateVoutAParam(sgks_vo_dev_info_s *pinfo)
{
    int                                   errorCode = 0;
    sgks_vo_hv_size_info_s                sink_hv;
    sgks_vo_hv_sync_info_s                sink_sync;
    sgks_vo_window_info_s                 sink_window;
    sgks_vio_src_video_info_s              sink_video_info;
    sgks_video_source_clock_setup_s       clk_setup;
    sgks_vd_config_s                      sink_cfg;
    sgks_video_source_csc_info_s          sink_csc;
    u32 sx=0, ex=0, sy=0, ey=0, fr=0;


    sgks_vo_deviceInfo_s *voutA_Device = &pinfo->vo_user_param;

    sink_window.start_x   = voutA_Device->video_offset.offset_x;
    sink_window.start_y   = voutA_Device->video_offset.offset_y;
    sink_window.end_x     = sink_window.start_x + voutA_Device->video_size.video_width - 1;
    sink_window.end_y     = sink_window.start_y + voutA_Device->video_size.video_height - 1;

    if (voutA_Device->format == SGKS_VIDEO_FORMAT_INTERLACE)
    {
        sink_window.start_y  >>= 1;
        sink_window.end_y    >>= 1;
    }

    sgks_mpi_vo_set_video_size(pinfo, &sink_window);



    sgks_mpi_vo_conv_active_win(voutA_Device, &sx, &ex, &sy, &ey, &fr);
    sink_window.start_x = sx;
    sink_window.end_x = ex;
    sink_window.start_y = sy;
    sink_window.end_y = ey;
    sink_window.width = (ex - (sx) + 1) >> 1;
    sink_window.field_reverse = fr;

    sgks_mpi_vo_set_active_win(pinfo, &sink_window);


    sgks_dsp_cmd_vo_video_setup_s video_args;
    sgks_mpi_vo_get_setup(pinfo, &video_args);

    video_args.en                  = voutA_Device->video_en;

	switch (voutA_Device->video_rotate_flip_ctrl)
	{
		case SGKS_VO_NORMAL_DISPLAY:
			video_args.flip                = 0;
    		video_args.rotate              = 0;
			break;
		case SGKS_VO_RIGHT_ROTATE_90:
			video_args.flip                = 0;
    		video_args.rotate              = 1;
			break;
		case SGKS_VO_LEVEL_ROTATE_180:
			video_args.flip                = 1;
    		video_args.rotate              = 0;
			break;
		case SGKS_VO_LEFT_ROTATE_90:
			video_args.flip                = 1;
    		video_args.rotate              = 1;
			break;
		case SGKS_VO_LEVEL_FLIP_180:
			video_args.flip                = 2;
    		video_args.rotate              = 0;
			break;
		case SGKS_VO_LEFT_ROTATE_90_FLIP_180:
			video_args.flip                = 2;
    		video_args.rotate              = 1;
			break;
		case SGKS_VO_LEFT_RIGHT_LEFT_180:
			video_args.flip                = 3;
    		video_args.rotate              = 0;
			break;
		case SGKS_VO_RIGHT_ROTATE_90_FLIP_180:
			video_args.flip                = 3;
    		video_args.rotate              = 1;
			break;
		default:
    		video_args.flip                = 0;
    		video_args.rotate              = 0;
			break;
	}

    if (voutA_Device->vo_src != SGKS_VO_SRC_ENC)
    {
        video_args.default_img_y_addr  = voutA_Device->disp_bank_phy;
        video_args.default_img_uv_addr = voutA_Device->disp_bank_phy + voutA_Device->yuv_width * voutA_Device->yuv_height;
        //video_args.default_img_pitch   = voutA_Device->yuv_width;
    }

    sgks_mpi_vo_set_setup(pinfo, &video_args);



    sgks_dsp_cmd_vo_osd_setup_s osd_args;
    osd_args.en = 0;
    sgks_vo_set_osd(pinfo, &osd_args);


    ////////////////////////////////////

    sgks_mpi_vo_select_display_input(pinfo, voutA_Device->display_input);
    sgks_vo_set_bg_color(pinfo, &voutA_Device->bg_color);

    /////////////////////////////////////





    return SGKS_SUCCESS;

}


static int sgks_mpi_vo_initVoutAParam(sgks_vo_dev_info_s *pinfo)
{

    u8 *msg_buf = NULL;
    u8 *maddr = NULL;
    SGKS_MDI_DRV_BUFF(msg_buf);

    sgks_vo_deviceInfo_s *voutA_Device        = &pinfo->vo_user_param;

    pinfo->status                              = SGKS_VIDEO_SOURCE_STATUS_IDLE;
    //pinfo->irq_counter                         = 0;
    //pinfo->wait_num                            = 0;
    //pinfo->timeout                             = 0;
    //snprintf(pinfo->event_proc.proc_name, sizeof(pinfo->event_proc.proc_name), "%s_event", pvi->name);

    pinfo->osd_setup_flag                      = SGKS_VO_SETUP_NA;
    pinfo->osd_clut_setup_flag                 = SGKS_VO_SETUP_NA;
    pinfo->dram_tv_flag                        = SGKS_VO_SETUP_NA;

    memset(&pinfo->mixer_setup, 0, sizeof(sgks_dsp_cmd_vo_mixer_setup_s));
    pinfo->mixer_setup.cmd_code                = SGKS_DSP_CMD_VO_MIXER_SETUP;
    pinfo->mixer_setup.vo_id                   = SGKS_VOUT_A;
    pinfo->mixer_setup.highlight_thresh        = 0xff;
    pinfo->mixer_setup.highlight_y             = 0x00;
    pinfo->mixer_setup.highlight_u             = 0x00;
    pinfo->mixer_setup.highlight_v             = 0x00;


    memset(&pinfo->video_setup, 0, sizeof(sgks_dsp_cmd_vo_video_setup_s));
    pinfo->video_setup.cmd_code                = SGKS_DSP_CMD_VO_VIDEO_SETUP;
    pinfo->video_setup.vo_id                   = SGKS_VOUT_A;
    pinfo->video_setup.src                     = voutA_Device->vo_src;
	pinfo->video_setup.default_img_pitch       = 512;
	pinfo->video_setup.data_src                = 1;
#if 0
    pinfo->video_setup.default_img_y_addr		= 0xCEC0A000;
    pinfo->video_setup.default_img_uv_addr     = 0xCEC6E140;
    pinfo->video_setup.default_img_pitch       = 0x1E0;
#endif

    memset(&pinfo->default_img_setup, 0, sizeof(sgks_dsp_cmd_vo_default_img_setup_s));
    pinfo->default_img_setup.cmd_code          = SGKS_DSP_CMD_VO_DEFAULT_IMG_SETUP;
    pinfo->default_img_setup.vo_id             = SGKS_VOUT_A;
#if 1
    pinfo->default_img_setup.default_img_pitch = 512;
    pinfo->default_img_setup.mjpeg_yuv         = 0x1;
    pinfo->default_img_setup.mjpeg_width       = 512;
    pinfo->default_img_setup.mjpeg_height      = 854;
    pinfo->default_img_setup.newest_bank_daddr = 0xCEC0F000;
    pinfo->default_img_setup.bank0_daddr       = 0xCEC0F040;
#endif

    pinfo->dram_osd                            = (sgks_dram_osd_s *)voutA_Device->dram_osd_phy;



    sgks_mdi_mmap_s *mmap 	  = msg_buf;
    mmap->mmap_phy_start_addr = voutA_Device->dram_osd_phy;
    mmap->mmap_phy_size       = voutA_Device->dram_osd_size;
    SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_MMAP, 0, sizeof(sgks_mdi_mmap_s), SGKS_ERR_SYS_DRIVERIOCTLERR);
    maddr = mmap->mmap_user_start_addr;

    sgks_dram_osd_s *pdram_osd   		 = maddr;
    pdram_osd->osd_buf_dram_addr         = 0;
    pdram_osd->osd_buf_pitch             = 0;
    pdram_osd->osd_buf_repeat_field      = 0;

    SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_UNMMAP, 0, sizeof(sgks_mdi_mmap_s), SGKS_ERR_SYS_DRIVERIOCTLERR);

    memset(&pinfo->osd_setup, 0, sizeof(sgks_dsp_cmd_vo_osd_setup_s));
    pinfo->osd_setup.cmd_code                  = SGKS_DSP_CMD_VO_OSD_SETUP;
    pinfo->osd_setup.vo_id                     = SGKS_VOUT_A;
    pinfo->osd_setup.osd_buf_info_dram_addr    = voutA_Device->dram_osd_phy;

    memset(&pinfo->osd_buf_setup, 0, sizeof(sgks_dsp_cmd_vo_osd_buf_setup_s));
    pinfo->osd_buf_setup.cmd_code              = SGKS_DSP_CMD_VO_OSD_BUFFER_SETUP;
    pinfo->osd_buf_setup.vo_id                 = SGKS_VOUT_A;


    memset(&pinfo->osd_clut_setup, 0, sizeof(sgks_dsp_cmd_vo_osd_clut_setup_s));
    pinfo->osd_clut_setup.cmd_code             = SGKS_DSP_CMD_VO_OSD_CLUT_SETUP;
    pinfo->osd_clut_setup.vo_id                = SGKS_VOUT_A;

#if 0
    if((SGKS_VO_CLUT_SIZE * 4) > DSP_OSD_CLUT_DRAM_SIZE)
    {
        Printf("error: please malloc larger memory for OSD CLUT, current:0x%x, need:0x%x\n", DSP_OSD_CLUT_DRAM_SIZE, (SGKS_VO_CLUT_SIZE * 4));
        return -1;
    }
#endif

    pinfo->dram_clut                           = voutA_Device->dram_clut_phy;
    pinfo->osd_clut_setup.clut_dram_addr       = voutA_Device->dram_clut_phy;


    memset(&pinfo->display_setup, 0, sizeof(sgks_dsp_cmd_vo_display_setup_s));
    pinfo->display_setup.cmd_code              = SGKS_DSP_CMD_VO_DISPLAY_SETUP;
    pinfo->display_setup.vo_id                 = SGKS_VOUT_A;
    pinfo->display_setup.disp_config_dram_addr = voutA_Device->disp_config_dram_addr_phy;

#if 0
    pinfo->tv_setup.cmd_code                   = SGKS_DSP_CMD_VO_TV_SETUP;
    pinfo->tv_setup.vo_id                      = SGKS_VOUT_A;
    pinfo->tv_setup.tv_config_dram_addr        = (u32)&vo_dma_info->dram_tv;
#endif
    memset(&pinfo->reset, 0, sizeof(sgks_dsp_cmd_vo_reset_s));
    pinfo->reset.cmd_code                      = SGKS_DSP_CMD_VO_RESET;
    pinfo->reset.vo_id                         = SGKS_VOUT_A;

    memset(&pinfo->csc_setup, 0, sizeof(sgks_dsp_cmd_vo_display_csc_setup_s));
    pinfo->csc_setup_flag                      = SGKS_VO_SETUP_NA;
    pinfo->csc_setup.cmd_code                  = SGKS_DSP_CMD_VO_DISPLAY_CSC_SETUP;
    pinfo->csc_setup.vo_id                     = SGKS_VOUT_A;

    memset(&pinfo->pip_config_default, 0, sizeof(sgks_dsp_cmd_pip_config_default_s));
    pinfo->pip_config_default.cmd_code         = SGKS_DSP_CMD_IPCAM_PIP_CONFIG;

    return SGKS_SUCCESS;

}


int sgks_mpi_vo_Start(sgks_mpi_manager_s *mpi)
{

    int i = 0;

    u32 *vo_handle                  = &mpi->mpi_vo_handle;


    for (i=0; i<mpi->mpi_vo_num; i++)
    {

        if (mpi->mpi_vo_dev[i].vo_user_param.id == SGKS_VOUT_A)
        {
            sgks_mpi_vo_initVoutAParam(&mpi->mpi_vo_dev[i]);
            sgks_mpi_vo_UpdateVoutAParam(&mpi->mpi_vo_dev[i]);
            sgks_voutA_run(&mpi->mpi_vo_dev[i]);
        }

    }

    return SGKS_SUCCESS;

}

static int sgks_mpi_vo_CheckMemAddrPageAlign(sgks_vo_deviceInfo_s *vo_user_param)
{

    int i = 0;

    u8 *msg_buf = NULL;
    SGKS_MDI_DRV_BUFF(msg_buf);
    SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_GETPAGESIZE, 0, sizeof(sgks_get_pagesize_s), SGKS_ERR_SYS_DRIVERIOCTLERR);
    sgks_get_pagesize_s *kernel_page = msg_buf;
    u32 page_size = kernel_page->page_size;

    SGKS_MPI_CHECK_MEM_PAGE_ALIGN((u32)vo_user_param->disp_config_dram_addr_phy, 	page_size, SGKS_ERR_SYS_INITMEMPARAMFAIL);
    SGKS_MPI_CHECK_MEM_PAGE_ALIGN((u32)vo_user_param->dram_clut_phy,			 	page_size, SGKS_ERR_SYS_INITMEMPARAMFAIL);
    SGKS_MPI_CHECK_MEM_PAGE_ALIGN((u32)vo_user_param->dram_osd_phy, 				page_size, SGKS_ERR_SYS_INITMEMPARAMFAIL);
    SGKS_MPI_CHECK_MEM_PAGE_ALIGN((u32)vo_user_param->tv_config_dram_addr_phy, 	page_size, SGKS_ERR_SYS_INITMEMPARAMFAIL);
    SGKS_MPI_CHECK_MEM_PAGE_ALIGN((u32)vo_user_param->disp_bank_phy, 				page_size, SGKS_ERR_SYS_INITMEMPARAMFAIL);

    return SGKS_SUCCESS;
}

int sgks_mpi_vo_GetScreenParam(sgks_mpi_vo_device_s *vo_dev)
{
	int ret  = -1;
	int fd = -1;
	sgks_vout_Mipi_Drv_Cfg_t *mipicfg;
    
	fd = open("/dev/sgks_vout", O_RDWR, 0);
    if(fd < 0)
    {
        printf("Open sgks_vout err! \r\n");
        return -1;
    }

	msg_t ioctl_msg;
	memset(&ioctl_msg, 0, sizeof(ioctl_msg));
	ioctl_msg.msg_head.msg_type    = SGKS_LCD_OPERATION_GETDEVINFO;
	ioctl_msg.msg_head.msg_size    = sizeof(sgks_vout_Mipi_Drv_Cfg_t);
	
    if (ioctl(fd, SGKS_LCD_IOCTL_OPERATION, &ioctl_msg) < 0)
    {
        printf("Ioctl reading fixed information.  \r\n");
        return -1;
    }
	
	mipicfg = (sgks_vout_Mipi_Drv_Cfg_t *)ioctl_msg.msg_data;

    //sprintf(vo_dev->vo_deviceinfo[0].device_node, "/dev/sgks_vout");
	
    vo_dev->vo_deviceinfo[0].type      		  		= mipicfg->TYPE;
    vo_dev->vo_deviceinfo[0].mode              		= mipicfg->MODE;

    /* 分辨率设置 */
    vo_dev->vo_deviceinfo[0].video_info.width  		= mipicfg->VACT;
    vo_dev->vo_deviceinfo[0].video_info.height 		= mipicfg->HACT;
	
	/* 分辨率设置 */
    vo_dev->vo_deviceinfo[0].video_size.video_width  = mipicfg->HACT;
    vo_dev->vo_deviceinfo[0].video_size.video_height = mipicfg->VACT;
    vo_dev->vo_deviceinfo[0].video_size.vo_width     = mipicfg->HACT;
    vo_dev->vo_deviceinfo[0].video_size.vo_height    = mipicfg->VACT;

	close(fd);

	return SGKS_SUCCESS;

}

int sgks_mpi_vo_init(sgks_mpi_vo_device_s *vo_device)
{

    int ret = 0;
    int i = 0;

    /**************************/
	sgks_mpi_vo_GetScreenParam(vo_device);
	
    sgks_mpi_manager_s *mpi = mpi_get_managerHanle();	

    if (sgks_mpi_sys_GetModuleInitStatus(mpi ,MPI_MODULE_VOUT_ID) == MPI_MODULE_STATUS_INIT)
    {
        Printf("sgks_mpi_vi already init\n");
        return SGKS_SUCCESS;
    }

    mpi->curr_module_id		= MPI_MODULE_VOUT_ID;

    ret = sgks_mpi_sys_GetDriverHandle(mpi);
    if (ret != SGKS_SUCCESS)
        return ret;

    ret = sgks_mpi_vi_OpenDeviceNode(mpi);
    if (ret != SGKS_SUCCESS)
    {
        return ret;
    }

    mpi->mpi_vo_num = vo_device->vo_device_num;

    for(i = 0; i < vo_device->vo_device_num; i++)
    {
        memcpy(&mpi->mpi_vo_dev[i].vo_user_param, &vo_device->vo_deviceinfo[i], sizeof(sgks_vo_deviceInfo_s));

        if ((ret = sgks_mpi_vo_CheckMemAddrPageAlign(&mpi->mpi_vo_dev[i].vo_user_param)) != SGKS_SUCCESS)
        {
            return ret;
        }
    }

    sgks_mpi_vo_OpenDeviceNode(vo_device,mpi->mpi_vo_handle);

    sgks_mpi_vo_Start(mpi);

    sgks_mpi_sys_UpdateModuleInitStatus(mpi, MPI_MODULE_VOUT_ID, MPI_MODULE_STATUS_INIT);

	ret = sgks_mpi_vo_YuvMmapPhyAddr();
	if (ret != SGKS_SUCCESS)
	{	
		printf("sgks mpi vo show yuv mapPhyAddr error \n\r");
		return ret;
	}

    return SGKS_SUCCESS;

}



static int sgks_mpi_vo_tv_setup(sgks_vo_dev_info_s *pinfo)
{

    u8 *msg_buf = NULL;
    SGKS_MDI_DRV_BUFF(msg_buf);
    sgks_mdi_opt_d_cache_s *cache 			= msg_buf;
	cache->cache_type                		= SGKS_OPT_D_CACHE_CLAEN;
    cache->start                     		= pinfo->vo_user_param.tv_config_dram_addr_phy;
    cache->size                      		= sizeof(pinfo->dram_tv);
    SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_OPT_D_CACHE, 0, sizeof(sgks_mdi_opt_d_cache_s), SGKS_ERR_SYS_DRIVERIOCTLERR);



    mpi_cmd_hex(pinfo->tv_setup, cmd_code);
    mpi_cmd(pinfo->tv_setup,      vo_id);
    mpi_cmd(pinfo->tv_setup,      tv_config_dram_addr);

    int ret = sgks_mpi_cmd_Send(&pinfo->tv_setup, sizeof(sgks_dsp_cmd_vo_tv_setup_s));
    if (ret != SGKS_SUCCESS)
    {
        return ret;
    }

    return SGKS_SUCCESS;


}


static inline int sgks_mpi_vo_SetLcdClk(SGKS_VO_CLK_TYPE_E type)
{
    unsigned long *reg1, *reg2, *reg3;
    u8* msg_buf = NULL;
    SGKS_MDI_DRV_BUFF(msg_buf);
    sgks_mdi_reg_rw_s *reg = msg_buf;

    switch(type)
    {
    case SGKS_VO_CLK_13_5M:

        reg->reg_num =2;
        reg->reg_info[0].addr 		 = 0x801701d4;
        reg->reg_info[0].addr_type  = SGKS_MDI_REG_ADDR_TYPE_PHY;
        reg->reg_info[0].val  		= 0x01;
        reg->reg_info[1].addr 		= 0x801700A0;
        reg->reg_info[1].addr_type  = SGKS_MDI_REG_ADDR_TYPE_PHY;
        reg->reg_info[1].val  		= 0x40;
        SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_REG_WRITE, 0, sizeof(sgks_mdi_reg_rw_s), SGKS_ERR_SYS_DRIVERIOCTLERR);

        break;
    case SGKS_VO_CLK_27M:

        reg->reg_num =1;
        reg->reg_info[0].addr 		= 0x801701d4;
        reg->reg_info[0].addr_type  = SGKS_MDI_REG_ADDR_TYPE_PHY;
        reg->reg_info[0].val  		= 0x01;
        SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_REG_WRITE, 0, sizeof(sgks_mdi_reg_rw_s), SGKS_ERR_SYS_DRIVERIOCTLERR);
        break;

    case SGKS_VO_CLK_60M:/*lCD*/


        reg->reg_num =2;
        reg->reg_info[0].addr = 0x801701d4;
        reg->reg_info[0].addr_type  = SGKS_MDI_REG_ADDR_TYPE_PHY;
        reg->reg_info[0].val  = 0x00;
        reg->reg_info[1].addr = 0x801700d4;
        reg->reg_info[1].addr_type  = SGKS_MDI_REG_ADDR_TYPE_PHY;
        reg->reg_info[1].val  = 0x00;
        SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_REG_WRITE, 0, sizeof(sgks_mdi_reg_rw_s), SGKS_ERR_SYS_DRIVERIOCTLERR);

        break;

    case SGKS_VO_CLK_72_25M:/*MIPI*/


        reg->reg_num =3;
        reg->reg_info[0].addr = 0x80170274;
        reg->reg_info[0].addr_type  = SGKS_MDI_REG_ADDR_TYPE_PHY;
        reg->reg_info[0].val  = 0x01;
        reg->reg_info[1].addr = 0x801700d4;
        reg->reg_info[1].addr_type  = SGKS_MDI_REG_ADDR_TYPE_PHY;
        reg->reg_info[1].val  = 0x00;
        reg->reg_info[2].addr = 0x801701d4;
        reg->reg_info[2].addr_type  = SGKS_MDI_REG_ADDR_TYPE_PHY;
        reg->reg_info[2].val  = 0x00;
        SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_REG_WRITE, 0, sizeof(sgks_mdi_reg_rw_s), SGKS_ERR_SYS_DRIVERIOCTLERR);

        break;

    }

    return SGKS_SUCCESS;

}




static inline int sgks_mpi_vo_VoutA_DispParam_init(VOUT_DISPLAY_PARAMS_S *vout_display_params_p, int device_type)
{
    u32 tvfp, tvbp, thfp, thbp;
    vout_display_params_p->clk_per_pixel		= 1;
    vout_display_params_p->interlace			= 0;
    vout_display_params_p->d_clk_edge_sel      	= 1;
    u8* msg_buf = NULL;
    sgks_mdi_reg_rw_s *mdi_reg = NULL;

    if(device_type == SGKS_VO_SINK_TYPE_RGB_800_480)
    {
        vout_display_params_p->vour_a_freq		   = 27000000;//27000000;    //MHz
        vout_display_params_p->hs_back_porch_typ	   = 46;    //THBP
        vout_display_params_p->hs_front_porch_typ   = 42;	 //THFP
        vout_display_params_p->vs_back_porch_typ	   = 8;//8;//23;	 //TVBP
        vout_display_params_p->vs_front_porch_typ	   = 22;    //TVFP
        thbp                                           = vout_display_params_p->hs_back_porch_typ;
        thfp                                           = vout_display_params_p->hs_front_porch_typ;
        tvbp                                           = vout_display_params_p->vs_back_porch_typ;
        tvfp                                           = vout_display_params_p->vs_front_porch_typ;

        vout_display_params_p->frameRate            = 30;
        vout_display_params_p->frame_width          = 800 + thbp + thfp - 1;
        vout_display_params_p->frame_height         = 480 + tvbp + tvfp - 1;
        vout_display_params_p->offset_width         = 0;
        vout_display_params_p->offset_height        = 0;

    }
    else if(device_type == SGKS_VO_SINK_TYPE_RGB_1280_272)
    {
        vout_display_params_p->lcd_screen_width       = 1280;
        vout_display_params_p->lcd_screen_height      = 272;
        vout_display_params_p->clk_per_pixel		    = 1;
        vout_display_params_p->interlace			    = 0;
        vout_display_params_p->d_clk_edge_sel        = 1;
        vout_display_params_p->vour_a_freq		    = 27000000;//27000000;    //MHz
        vout_display_params_p->hs_back_porch_typ	    = 88;    //THBP
        vout_display_params_p->hs_front_porch_typ	    = 72;	 //THFP
        vout_display_params_p->vs_back_porch_typ	    = 32;//8;//23;	 //TVBP
        vout_display_params_p->vs_front_porch_typ	    = 21;    //TVFP

        thbp                                            = vout_display_params_p->hs_back_porch_typ;
        thfp                                            = vout_display_params_p->hs_front_porch_typ;
        tvbp                                            = vout_display_params_p->vs_back_porch_typ;
        tvfp                                            = vout_display_params_p->vs_front_porch_typ;

        vout_display_params_p->frameRate             = 30;
        vout_display_params_p->frame_width           = vout_display_params_p->lcd_screen_width + thbp + thfp;
        vout_display_params_p->frame_height          = vout_display_params_p->vour_a_freq / vout_display_params_p->frameRate / vout_display_params_p->frame_width;
        vout_display_params_p->offset_width          = vout_display_params_p->frame_width - vout_display_params_p->lcd_screen_width - thbp - thfp;
        vout_display_params_p->offset_height         = vout_display_params_p->frame_height - vout_display_params_p->lcd_screen_height - tvbp - tvfp;

    }
    else if(device_type == SGKS_VO_SINK_TYPE_MIPI_1920_480)
    {
        vout_display_params_p->vour_a_freq				= 74250000;  //KHz
        vout_display_params_p->hs_back_porch_typ			= 20;
        vout_display_params_p->hs_front_porch_typ			= 5;
        vout_display_params_p->vs_back_porch_typ			= 50;
        vout_display_params_p->vs_front_porch_typ			= 50;

        thbp 												= vout_display_params_p->hs_back_porch_typ;
        thfp  												= vout_display_params_p->hs_front_porch_typ;
        tvbp 												= vout_display_params_p->vs_back_porch_typ;
        tvfp  												= vout_display_params_p->vs_front_porch_typ;

        vout_display_params_p->frameRate 					= 50;
        vout_display_params_p->frame_width 				= 2550;
        vout_display_params_p->frame_height 				= (74250000 / (vout_display_params_p->frameRate)) / (vout_display_params_p->frame_width);
        vout_display_params_p->offset_width 				= vout_display_params_p->frame_width - (thbp + thfp + vout_display_params_p->lcd_screen_width * vout_display_params_p->clk_per_pixel);
        vout_display_params_p->offset_height 				= vout_display_params_p->frame_height - (tvbp + tvfp + vout_display_params_p->lcd_screen_height);

    }
    else if(device_type == SGKS_VO_SINK_TYPE_MIPI_1280_320)
    {

        vout_display_params_p->vour_a_freq				= 74250000;  //KHz
        vout_display_params_p->hs_back_porch_typ			= 80;
        vout_display_params_p->hs_front_porch_typ			= 80;
        vout_display_params_p->vs_back_porch_typ			= 28;
        vout_display_params_p->vs_front_porch_typ			= 10;

        thbp 												= vout_display_params_p->hs_back_porch_typ;
        thfp  												= vout_display_params_p->hs_front_porch_typ;
        tvbp 												= vout_display_params_p->vs_back_porch_typ;
        tvfp  												= vout_display_params_p->vs_front_porch_typ;

        vout_display_params_p->frameRate 					= 50;
        vout_display_params_p->frame_width 				= 2250;
        vout_display_params_p->frame_height 				= (74250000 / (vout_display_params_p->frameRate)) / (vout_display_params_p->frame_width);
        vout_display_params_p->offset_width 				= vout_display_params_p->frame_width - (thbp + thfp + vout_display_params_p->lcd_screen_width * vout_display_params_p->clk_per_pixel);
        vout_display_params_p->offset_height 				= vout_display_params_p->frame_height - (tvbp + tvfp + vout_display_params_p->lcd_screen_height);

    }
    else if(device_type == SGKS_VO_SINK_TYPE_MIPI_480_1280)
    {

        vout_display_params_p->vour_a_freq				= 27000000;  //KHz
        vout_display_params_p->hs_back_porch_typ			= 50;
        vout_display_params_p->hs_front_porch_typ			= 50;
        vout_display_params_p->vs_back_porch_typ			= 30;
        vout_display_params_p->vs_front_porch_typ			= 30;

        thbp 												= vout_display_params_p->hs_back_porch_typ;
        thfp 												= vout_display_params_p->hs_front_porch_typ;
        tvbp 												= vout_display_params_p->vs_back_porch_typ;
        tvfp  												= vout_display_params_p->vs_front_porch_typ;

        vout_display_params_p->frameRate 					= 25;
        vout_display_params_p->frame_width 				= vout_display_params_p->lcd_screen_width + thbp + thfp;;
        vout_display_params_p->frame_height 				= (27000000 / (vout_display_params_p->frameRate)) / (vout_display_params_p->frame_width);
        vout_display_params_p->offset_width 				= vout_display_params_p->frame_width - (thbp + thfp + vout_display_params_p->lcd_screen_width * vout_display_params_p->clk_per_pixel);
        vout_display_params_p->offset_height 				= vout_display_params_p->frame_height - (tvbp + tvfp + vout_display_params_p->lcd_screen_height);

    }
    else if(device_type == SGKS_VO_SINK_TYPE_MIPI_480_854)
    {
        u32 frame_width, frame_height, theory_clk, vout_clk_div, actual_clk, offset_width, offset_height;
        u32 *reg;
        vout_display_params_p->vour_a_freq				= 74250000;  //KHz
        vout_display_params_p->hs_back_porch_typ			= 50;
        vout_display_params_p->hs_front_porch_typ			= 50;
        vout_display_params_p->vs_back_porch_typ			= 20;
        vout_display_params_p->vs_front_porch_typ			= 20;
        thbp 												= vout_display_params_p->hs_back_porch_typ;
        thfp 												= vout_display_params_p->hs_front_porch_typ;
        tvbp 												= vout_display_params_p->vs_back_porch_typ;
        tvfp  												= vout_display_params_p->vs_front_porch_typ;

        vout_display_params_p->frameRate 					= 30;
        frame_width  										= vout_display_params_p->lcd_screen_width + thbp + thfp;
        frame_height 										= vout_display_params_p->lcd_screen_height + tvbp + tvfp;
        theory_clk 											= frame_width * frame_height * vout_display_params_p->frameRate;
        vout_clk_div 										= 864000000 / theory_clk;
        actual_clk 											= 864000000 / vout_clk_div;
        frame_height 										= (actual_clk / (vout_display_params_p->frameRate)) / frame_width;
        offset_width 										= frame_width - (vout_display_params_p->lcd_screen_width + thbp + thfp);
        offset_height 										= frame_height - (vout_display_params_p->lcd_screen_height + tvbp + tvfp);

        //WRREG(0x801700A0,vout_clk_div);   //set clk div
        SGKS_MDI_DRV_BUFF(msg_buf);
        mdi_reg = msg_buf;
        mdi_reg->reg_num =1;
        mdi_reg->reg_info[0].addr     = 0x801700A0;
        mdi_reg->reg_info[0].addr_type = SGKS_MDI_REG_ADDR_TYPE_PHY;
        mdi_reg->reg_info[0].val      = vout_clk_div;
        mdi_reg->reg_info[0].delay_ms = 0;//2000;
        SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_REG_WRITE, 0, sizeof(sgks_mdi_reg_rw_s), SGKS_ERR_SYS_DRIVERIOCTLERR);

        vout_display_params_p->frame_width 				= frame_width;
        vout_display_params_p->frame_height 				= frame_height;
        vout_display_params_p->offset_width 				= offset_width;
        vout_display_params_p->offset_height 				= offset_height;

        Printf("frame_width:%d,frame_height:%d,offset_width:%d,offset_height:%d,vout_a_clk:%d,vout_clk_div:%d,",
               frame_width, frame_height, offset_width, offset_height, actual_clk, vout_clk_div);

    }
    else if(device_type == SGKS_VO_SINK_TYPE_BT1120)
    {

        vout_display_params_p->clk_per_pixel        		= 1;
        vout_display_params_p->interlace            		= 0;
        vout_display_params_p->d_clk_edge_sel       		= 0;
        vout_display_params_p->vour_a_freq		    	= 37125000;  //KHz
        vout_display_params_p->hs_back_porch_typ			= 720;
        vout_display_params_p->hs_front_porch_typ			= 20;
        vout_display_params_p->vs_back_porch_typ			= 0;
        vout_display_params_p->vs_front_porch_typ			= 0;
        thbp 												= vout_display_params_p->hs_back_porch_typ;
        thfp  												= vout_display_params_p->hs_front_porch_typ;
        tvbp 												= vout_display_params_p->vs_back_porch_typ;
        tvfp 												= vout_display_params_p->vs_front_porch_typ;
        vout_display_params_p->frameRate 					= 30;
        vout_display_params_p->frame_width 				= 1500;
        vout_display_params_p->frame_height 				= (37125000 / (vout_display_params_p->frameRate)) / (vout_display_params_p->frame_width);
        vout_display_params_p->offset_width 				= vout_display_params_p->frame_width - (thbp + thfp + vout_display_params_p->lcd_screen_width * vout_display_params_p->clk_per_pixel);
        vout_display_params_p->offset_height				= vout_display_params_p->frame_height - (tvbp + tvfp + vout_display_params_p->lcd_screen_height);

    }
    else if(device_type == SGKS_VO_SINK_TYPE_MIPI_400_1280)
    {
        u32 frame_width, frame_height, theory_clk, vout_clk_div, actual_clk, offset_width, offset_height;
        u32 *reg;

        vout_display_params_p->clk_per_pixel       = 1;
        vout_display_params_p->lcd_screen_width    = 400;
        vout_display_params_p->lcd_screen_height   = 1280;
        vout_display_params_p->frameRate           = 25;
        vout_display_params_p->hs_back_porch_typ   = 160;
        vout_display_params_p->hs_front_porch_typ  = 160;
        vout_display_params_p->vs_back_porch_typ   = 10;
        vout_display_params_p->vs_front_porch_typ  = 12;
        vout_display_params_p->interlace           = 0;
        vout_display_params_p->d_clk_edge_sel      = 0;

        vout_display_params_p->vour_a_freq         = 74250000;  //KHz

        thbp 										  = vout_display_params_p->hs_back_porch_typ;
        thfp										  = vout_display_params_p->hs_front_porch_typ;
        tvbp 										  = vout_display_params_p->vs_back_porch_typ;
        tvfp 										  = vout_display_params_p->vs_front_porch_typ;

        frame_width  								  = vout_display_params_p->lcd_screen_width + thbp + thfp;
        frame_height                                  = vout_display_params_p->lcd_screen_height + tvbp + tvfp;
        theory_clk                                    = frame_width * frame_height * vout_display_params_p->frameRate;
        vout_clk_div                                  = 864000000 / theory_clk;
        actual_clk                                    = 864000000 / vout_clk_div;
        frame_height                                  = (actual_clk / (vout_display_params_p->frameRate)) / frame_width;
        offset_width                                  = frame_width - (vout_display_params_p->lcd_screen_width + thbp + thfp);
        offset_height                                 = frame_height - (vout_display_params_p->lcd_screen_height + tvbp + tvfp);

        //WRREG(0x801700A0,vout_clk_div);   //set clk div
        SGKS_MDI_DRV_BUFF(msg_buf);
        mdi_reg = msg_buf;
        mdi_reg->reg_num =1;
        mdi_reg->reg_info[0].addr     = 0x801700A0;
        mdi_reg->reg_info[0].addr_type = SGKS_MDI_REG_ADDR_TYPE_PHY;
        mdi_reg->reg_info[0].val      = vout_clk_div;
        mdi_reg->reg_info[0].delay_ms = 2000;
        SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_REG_WRITE, 0, sizeof(sgks_mdi_reg_rw_s), SGKS_ERR_SYS_DRIVERIOCTLERR);


        vout_display_params_p->frame_width 			= frame_width;
        vout_display_params_p->frame_height 			= frame_height;
        vout_display_params_p->offset_width 			= offset_width;
        vout_display_params_p->offset_height 			= offset_height;

        Printf("frame_width:%d,frame_height:%d,offset_width:%d,offset_height:%d,vout_a_clk:%d,vout_clk_div:%d\n",
               frame_width, frame_height, offset_width, offset_height, actual_clk, vout_clk_div);

    }

    return SGKS_SUCCESS;

}




static inline void sgks_mpi_vo_SetVoutAdispalysize(VOUT_DISPLAY_PARAMS_S *dispParam, unsigned int *dram_param_displaylocal_p)
{
    VdHV vout_a_frame_size0, vout_a_frame_size1;
    VdHV vout_a_active_start0, vout_a_active_start1;
    VdHV vout_a_active_end0, vout_a_active_end1;

    //init
    vout_a_frame_size0.w = 0;
    vout_a_frame_size1.w = 0;
    vout_a_active_start0.w = 0;
    vout_a_active_end0.w = 0;
    vout_a_active_start1.w = 0;
    vout_a_active_end1.w = 0;

    if(dispParam->digital_out_mode == 4)  //BT656
    {
        vout_a_frame_size0.s.h	   	= vout_a_bt656_para[dispParam->vout_a_format][2]; //active_h_end
        vout_a_frame_size0.s.v		= vout_a_bt656_para[dispParam->vout_a_format][5]; //v_end
        vout_a_active_start0.s.h	= vout_a_bt656_para[dispParam->vout_a_format][1]; //active_h_str
        vout_a_active_start0.s.v	= vout_a_bt656_para[dispParam->vout_a_format][3]; //active_v_str
        vout_a_active_end0.s.h		= vout_a_bt656_para[dispParam->vout_a_format][2]; //active_h_end
        vout_a_active_end0.s.v		= vout_a_bt656_para[dispParam->vout_a_format][4]; //active_v_end

        if(dispParam->vout_a_format >= 10)  //10: OWN1080P25
        {
            dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_656_VBIT]		  = ((vout_a_active_end0.s.v + 1) << 16) | (vout_a_active_start0.s.v << 0)  ; //row
            dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_656_SAV_START]	  =  vout_a_active_start0.s.h - 4;
        }
    }
    else
    {
        vout_a_frame_size0.s.h		= dispParam->frame_width - 1;
        vout_a_frame_size0.s.v		= dispParam->frame_height - 1;
        vout_a_active_start0.s.h	= dispParam->hs_back_porch_typ + dispParam->offset_width;
        vout_a_active_start0.s.v	= dispParam->vs_back_porch_typ + dispParam->offset_height;
        vout_a_active_end0.s.h		= vout_a_active_start0.s.h + dispParam->lcd_screen_width * dispParam->clk_per_pixel - 1;
        vout_a_active_end0.s.v		= vout_a_active_start0.s.v + dispParam->lcd_screen_height - 1;
    }

    vout_a_active_start1.s.h	= vout_a_active_start0.s.h;
    vout_a_active_end1.s.h		= vout_a_active_end0.s.h;

    if(dispParam->interlace == 1)
    {
        vout_a_frame_size1.s.v 		= vout_a_frame_size0.s.v + 1;
        vout_a_active_start1.s.v 	= vout_a_active_start0.s.v + 1;
        vout_a_active_end1.s.v 		= vout_a_active_end0.s.v + 1;
    }
    else
    {
        vout_a_frame_size1.s.v 		= vout_a_frame_size0.s.v;
        vout_a_active_start1.s.v 	= vout_a_active_start0.s.v;
        vout_a_active_end1.s.v 		= vout_a_active_end0.s.v;
    }

    dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_FRAME_SIZE_FIELD0]		     = vout_a_frame_size0.w;
    dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_FRAME_SIZE_FIELD1]		     = vout_a_frame_size1.w;
    dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_ACTIVE_REGION_START_FIELD0]  = vout_a_active_start0.w;
    dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_ACTIVE_REGION_END_0] 	     = vout_a_active_end0.w;
    dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_ACTIVE_REGION_START_FIELD1]  = vout_a_active_start1.w;
    dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_ACTIVE_REGION_END_1] 	     = vout_a_active_end1.w;


}


static inline int sgks_mpi_vo_BT1120HardwareConfig(void)
{
    u8* msg_buf = NULL;
    SGKS_MDI_DRV_BUFF(msg_buf);
    sgks_mdi_reg_rw_s *reg = msg_buf;

    reg->reg_num =1;
    reg->reg_info[0].addr      = 0x70020E04;
    reg->reg_info[0].addr_type = SGKS_MDI_REG_ADDR_TYPE_PHY;
    SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_REG_READ, 0, sizeof(sgks_mdi_reg_rw_s), SGKS_ERR_SYS_DRIVERIOCTLERR);

    //bt1120 en
    reg->reg_info[0].val      |= 0x8;
    reg->reg_info[0].delay_ms = 0;
    SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_REG_WRITE, 0, sizeof(sgks_mdi_reg_rw_s), SGKS_ERR_SYS_DRIVERIOCTLERR);


    memset(reg, 0, sizeof(sgks_mdi_reg_rw_s));
    reg->reg_num 				= 1;
    reg->reg_info[0].addr 		= 0x80170208;
    reg->reg_info[0].addr_type  = SGKS_MDI_REG_ADDR_TYPE_PHY;
    SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_REG_READ, 0, sizeof(sgks_mdi_reg_rw_s), SGKS_ERR_SYS_DRIVERIOCTLERR);

    reg->reg_info[0].val      &= 0xFFFFFFFB;
    reg->reg_info[0].delay_ms = 0;
    SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_REG_WRITE, 0, sizeof(sgks_mdi_reg_rw_s), SGKS_ERR_SYS_DRIVERIOCTLERR);

}

static inline void sgks_mpi_vo_display_config(unsigned int *dram_param_displaylocal_p, int device_type, unsigned int w, unsigned int h, int id)
{
    VdCtrl	vout_a_display_ctrl;
    VdDigitalOutputMode vout_a_out_mode;
    VOUT_DISPLAY_PARAMS_S vout_display_params = {0};

    if(id != SGKS_VOUT_A)
    {
        printf("set display :vout id err\n");
        return ;
    }

    vout_display_params.lcd_screen_width  = w;
    vout_display_params.lcd_screen_height = h;
    vout_a_display_ctrl.w                 = 0;

    if(device_type == SGKS_VO_SINK_TYPE_RGB_800_480)
    {

        sgks_mpi_vo_SetLcdClk(SGKS_VO_CLK_13_5M);
        sgks_mpi_vo_VoutA_DispParam_init(&vout_display_params, device_type);
        sgks_mpi_vo_SetVoutAdispalysize(&vout_display_params, dram_param_displaylocal_p);

        vout_a_display_ctrl.s.format                                                  = vout_display_params.vout_a_format;
        vout_a_display_ctrl.s.interlace                                               = vout_display_params.interlace;
        vout_a_display_ctrl.s.digital_out_en                                          = 1;
        vout_a_out_mode.s.d_output_mode                                               = 6;
        vout_a_out_mode.s.d_clk_edge_sel                                              = vout_display_params.d_clk_edge_sel;

        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_CONTROL] 			      = vout_a_display_ctrl.w;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_OUTPUT]		      = vout_a_out_mode.w;;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_HSYNC_CONTROL]	  = (vout_display_params.offset_width << 16) | (15 << 0);
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_VSYNC_START_0]	  = (vout_display_params.offset_width << 16) | (vout_display_params.offset_height << 0);
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_VSYNC_END_0] 	  = (0 << 16) | (0 << 0);
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_0] 	  = 0x1f2604a8;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_1] 	  = 0x04a81ddd;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_2] 	  = 0x00010874;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_3] 	  = 0x1fff04a8;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_4] 	  = 0x004d072b;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_5] 	  = 0x7f087edf;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_6] 	  = 0x00ff0000;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_7] 	  = 0x00ff0000;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_8] 	  = 0x00ff0000;
        dram_param_displaylocal_p[0x174/4]                                       = 0x00060001;


    }
    else if(device_type == SGKS_VO_SINK_TYPE_RGB_1280_272)
    {

        sgks_mpi_vo_SetLcdClk(SGKS_VO_CLK_27M);
        sgks_mpi_vo_VoutA_DispParam_init(&vout_display_params, device_type);
        sgks_mpi_vo_SetVoutAdispalysize(&vout_display_params, dram_param_displaylocal_p);

        vout_a_display_ctrl.s.format                                                  = vout_display_params.vout_a_format;
        vout_a_display_ctrl.s.interlace                                               = vout_display_params.interlace;
        vout_a_display_ctrl.s.digital_out_en                                          = 1;
        vout_a_out_mode.s.d_output_mode                                               = 6;
        vout_a_out_mode.s.d_clk_edge_sel                                              = vout_display_params.d_clk_edge_sel;

        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_CONTROL] 			      = vout_a_display_ctrl.w;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_OUTPUT]		      = vout_a_out_mode.w;;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_HSYNC_CONTROL]	  = (vout_display_params.offset_width << 16) | (15 << 0);
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_VSYNC_START_0]	  = (vout_display_params.offset_width << 16) | (vout_display_params.offset_height << 0);
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_VSYNC_END_0] 	  = (0 << 16) | (0 << 0);
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_0] 	  = 0x1f2604a8;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_1] 	  = 0x04a81ddd;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_2] 	  = 0x00010874;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_3] 	  = 0x1fff04a8;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_4] 	  = 0x004d072b;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_5] 	  = 0x7f087edf;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_6] 	  = 0x00ff0000;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_7] 	  = 0x00ff0000;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_8] 	  = 0x00ff0000;
        dram_param_displaylocal_p[0x174/4] = 0x00060001;


    }
    else if((device_type == SGKS_VO_SINK_TYPE_MIPI_480_854) ||
            (device_type == SGKS_VO_SINK_TYPE_MIPI_1920_480)||
            (device_type == SGKS_VO_SINK_TYPE_MIPI_480_1280)||
            (device_type == SGKS_VO_SINK_TYPE_MIPI_400_1280))
    {

        sgks_mpi_vo_SetLcdClk(SGKS_VO_CLK_27M);
        sgks_mpi_vo_VoutA_DispParam_init(&vout_display_params, device_type);
        sgks_mpi_vo_SetVoutAdispalysize(&vout_display_params, dram_param_displaylocal_p);

        vout_a_display_ctrl.s.format                                                  = vout_display_params.vout_a_format;
        vout_a_display_ctrl.s.interlace                                               = vout_display_params.interlace;
        vout_a_display_ctrl.s.digital_out_en                                          = 1;
        vout_a_out_mode.w                                                             = 0x33400017;

        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_CONTROL] 			      = vout_a_display_ctrl.w;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_OUTPUT]		      = vout_a_out_mode.w;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_HSYNC_CONTROL]    = (vout_display_params.offset_width << 16) | (3 << 0);
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_VSYNC_START_0]    = (vout_display_params.offset_width << 16) | (vout_display_params.offset_height << 0);
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_VSYNC_END_0]      = (0 << 16) | (0 << 0);
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_0] 	  = 0x1f2604a8;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_1] 	  = 0x04a81ddd;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_2] 	  = 0x00010874;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_3] 	  = 0x1fff04a8;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_4] 	  = 0x004d072b;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_5] 	  = 0x7f087edf;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_6] 	  = 0x00ff0000;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_7] 	  = 0x00ff0000;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_8] 	  = 0x00ff0000;
        dram_param_displaylocal_p[0x174/4] 									  = 0x00060001;

    }
    else if(device_type == SGKS_VO_SINK_TYPE_MIPI_1280_320)
    {

        sgks_mpi_vo_SetLcdClk(SGKS_VO_CLK_72_25M);
        sgks_mpi_vo_VoutA_DispParam_init(&vout_display_params, device_type);
        sgks_mpi_vo_SetVoutAdispalysize(&vout_display_params, dram_param_displaylocal_p);

        vout_a_display_ctrl.s.format                                                 = vout_display_params.vout_a_format;
        vout_a_display_ctrl.s.interlace                                              = vout_display_params.interlace;
        vout_a_display_ctrl.s.digital_out_en                                         = 1;
        vout_a_out_mode.w                                                            = 0x33400017;

        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_CONTROL]                 = vout_a_display_ctrl.w;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_OUTPUT]          = vout_a_out_mode.w;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_HSYNC_CONTROL]   = (vout_display_params.offset_width << 16) | (3 << 0);
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_VSYNC_START_0]   = (vout_display_params.offset_width << 16) | (vout_display_params.offset_height << 0);
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_VSYNC_END_0]     = (0 << 16) | (0 << 0);
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_0]     = 0x1f2604a8;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_1]     = 0x04a81ddd;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_2]     = 0x00010874;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_3]     = 0x1fff04a8;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_4]     = 0x004d072b;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_5]     = 0x7f087edf;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_6]     = 0x00ff0000;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_7]     = 0x00ff0000;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_8]     = 0x00ff0000;
        dram_param_displaylocal_p[0x174/4] = 0x00060001;


    }
    else if(device_type == SGKS_VO_SINK_TYPE_BT1120)
    {

        sgks_mpi_vo_SetLcdClk(SGKS_VO_CLK_72_25M);
        sgks_mpi_vo_BT1120HardwareConfig();
        sgks_mpi_vo_VoutA_DispParam_init(&vout_display_params, device_type);

        vout_display_params.digital_out_mode = 4;//BT656
        vout_display_params.vout_a_format    = 12;  //HDMI_FORMAT
        vout_display_params.interlace        = vout_a_bt656_para[vout_display_params.vout_a_format][0];
        sgks_mpi_vo_SetVoutAdispalysize(&vout_display_params, dram_param_displaylocal_p);

        vout_a_display_ctrl.s.format                                                 = (vout_display_params.vout_a_format >= 10) ? 0 : vout_display_params.vout_a_format;
        vout_a_display_ctrl.s.interlace                                              = vout_display_params.interlace;
        vout_a_display_ctrl.s.digital_out_en                                         = 1;
        vout_a_out_mode.s.d_output_mode                                              = vout_display_params.digital_out_mode;
        vout_a_out_mode.s.d_clk_edge_sel                                             = vout_display_params.d_clk_edge_sel;

        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_CONTROL] 			     = vout_a_display_ctrl.w;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_OUTPUT]		     = vout_a_out_mode.w;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_HSYNC_CONTROL]   = (0 << 16) | (1 << 0);
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_VSYNC_START_0]   = (0 << 16) | (0 << 0);
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_VSYNC_END_0]     = (0 << 16) | (0 << 0);
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_VSYNC_START_1]   = (0 << 16) | (0 << 0);
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_VSYNC_END_1]     = (0 << 16) | (1 << 0);
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_0]     = 0x00000400;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_1]     = 0x00000000;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_2]     = 0x00000400;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_3]     = 0x00000000;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_4]     = 0x00000400;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_5]     = 0x00000400;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_6]     = 0x00fe0000;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_7]     = 0x00fe0000;
        dram_param_displaylocal_p[OFFSET_REG_VO_DISPLAY0_DIGITAL_CSC_PARAM_8]     = 0x00fe0000;


    }




}



static int sgks_mpi_vo_display_setup(sgks_vo_dev_info_s *pinfo)
{

#if 0
    if(1) //flag & SGKS_VIDEO_SOURCE_UPDATE_OSD_ON_STREAM
    {
        pinfo->dram_display.d_input_stream_enable.w = 0x01;
        pinfo->osd_setup.en = 0x00;
        pinfo->osd_setup_flag |= SGKS_VO_SETUP_CHANGED;
        pinfo->dram_tv_flag |= SGKS_VO_SETUP_CHANGED;
    }
    else //flag & SGKS_VIDEO_SOURCE_UPDATE_OSD_ON_CVBS
    {
        pinfo->dram_display.d_input_stream_enable.w = 0x00;
        pinfo->osd_setup.en = 0x01;
        pinfo->osd_setup_flag |= SGKS_VO_SETUP_CHANGED;
        pinfo->dram_tv_flag |= SGKS_VO_SETUP_CHANGED;
    }
    else

    {
        pinfo->dram_display.d_input_stream_enable.w = 0x00;
        pinfo->osd_setup.en = 0x00;
        pinfo->osd_setup_flag |= SGKS_VO_SETUP_CHANGED;
        pinfo->dram_tv_flag |= SGKS_VO_SETUP_CHANGED;
    }
#endif

    pinfo->dram_display.d_input_stream_enable.w  = 0x00;
    pinfo->osd_setup.en 						   = 0x00;
    pinfo->osd_setup_flag 						   |= SGKS_VO_SETUP_CHANGED;
    pinfo->dram_tv_flag                           |= SGKS_VO_SETUP_CHANGED;

    sgks_mpi_vo_display_config(&pinfo->dram_display, pinfo->vo_user_param.type, pinfo->video_setup.win_width, pinfo->video_setup.win_height, pinfo->mixer_setup.vo_id);

    u8 *msg_buf = NULL;
    SGKS_MDI_DRV_BUFF(msg_buf);
    sgks_mdi_mmap_s *mmap   = msg_buf;
    u8 *maddr 				= NULL;

    mmap->mmap_phy_start_addr = pinfo->vo_user_param.disp_config_dram_addr_phy;
    mmap->mmap_phy_size       = pinfo->vo_user_param.disp_config_dram_addr_size;
    SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_MMAP, 0, sizeof(sgks_mdi_mmap_s), SGKS_ERR_SYS_DRIVERIOCTLERR);
    maddr = mmap->mmap_user_start_addr;


    memcpy(maddr, (u8 *)&pinfo->dram_display, sizeof(pinfo->dram_display));
    //sgks_mpi_sys_DumpMemToFile("/home/n-disp.bin", maddr, sizeof(pinfo->dram_display));
    //sgks_mpi_sys_ReadFileToMem("/home/disp.bin", maddr, sizeof(pinfo->dram_display));

	SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_UNMMAP, 0, sizeof(sgks_mdi_mmap_s), SGKS_ERR_SYS_DRIVERIOCTLERR);

    //cache
    SGKS_MDI_DRV_CLEAN_DATABUFF();
    sgks_mdi_opt_d_cache_s *cache 		= msg_buf;
	cache->cache_type                	= SGKS_OPT_D_CACHE_CLAEN;
    cache->start                    	= pinfo->vo_user_param.disp_config_dram_addr_phy;
    cache->size                      	= sizeof(pinfo->dram_display);
    SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_OPT_D_CACHE, 0, sizeof(sgks_mdi_opt_d_cache_s), SGKS_ERR_SYS_DRIVERIOCTLERR);

    //send cmd
    mpi_cmd_hex(pinfo->display_setup, cmd_code);
    mpi_cmd(pinfo->display_setup,      vo_id);
    mpi_cmd_hex(pinfo->display_setup,      disp_config_dram_addr);

    int ret = sgks_mpi_cmd_Send(&pinfo->display_setup, sizeof(sgks_dsp_cmd_vo_display_setup_s));
    if (ret != SGKS_SUCCESS)
    {
        return ret;
    }

    return SGKS_SUCCESS;

}



static inline int sgks_mpi_vo_osd_setup(sgks_vo_dev_info_s *pinfo)
{
    //sgks_isp_clean_cache_vo((u8 *)pinfo->dram_osd, sizeof(sgks_dram_osd_s));

	

    mpi_cmd_hex(pinfo->osd_setup, cmd_code);
    mpi_cmd(pinfo->osd_setup, vo_id);
    mpi_cmd(pinfo->osd_setup, en);
    mpi_cmd(pinfo->osd_setup, src);
    mpi_cmd(pinfo->osd_setup, flip);
    mpi_cmd(pinfo->osd_setup, rescaler_en);
    mpi_cmd(pinfo->osd_setup, premultiplied);
    mpi_cmd(pinfo->osd_setup, global_blend);
    mpi_cmd(pinfo->osd_setup, win_offset_x);
    mpi_cmd(pinfo->osd_setup, win_offset_y);
    mpi_cmd(pinfo->osd_setup, win_width);
    mpi_cmd(pinfo->osd_setup, win_height);
    mpi_cmd(pinfo->osd_setup, rescaler_input_width);
    mpi_cmd(pinfo->osd_setup, rescaler_input_height);
    mpi_cmd(pinfo->osd_setup, osd_buf_dram_addr);
    mpi_cmd(pinfo->osd_setup, osd_buf_pitch);
    mpi_cmd(pinfo->osd_setup, osd_buf_repeat_field);
    mpi_cmd(pinfo->osd_setup, osd_direct_mode);
    mpi_cmd(pinfo->osd_setup, osd_transparent_color);
    mpi_cmd(pinfo->osd_setup, osd_transparent_color_en);
    mpi_cmd_hex(pinfo->osd_setup, osd_buf_info_dram_addr);

    int ret = sgks_mpi_cmd_Send(&pinfo->osd_setup, sizeof(sgks_dsp_cmd_vo_osd_setup_s));
    if (ret != SGKS_SUCCESS)
    {
        return ret;
    }
    return SGKS_SUCCESS;

}



static inline int sgks_mpi_vo_osd_clut_setup(sgks_vo_dev_info_s *pinfo)
{

    //sgks_isp_clean_cache_vo((u8 *)pinfo->dram_clut, SGKS_VO_CLUT_SIZE * 4/*sizeof(pinfo->dram_clut)*/);

    mpi_cmd_hex(pinfo->osd_clut_setup, cmd_code);
    mpi_cmd(pinfo->osd_clut_setup, vo_id);
    mpi_cmd_hex(pinfo->osd_clut_setup, clut_dram_addr);

    int ret = sgks_mpi_cmd_Send(&pinfo->osd_setup, sizeof(sgks_dsp_cmd_vo_osd_setup_s));
    if (ret != SGKS_SUCCESS)
    {
        return ret;
    }
    return SGKS_SUCCESS;
}


int sgks_mpi_vo_pip_config(sgks_vo_dev_info_s *pinfo)
{

    mpi_cmd_hex(pinfo->pip_config_default, cmd_code);
    mpi_cmd(pinfo->pip_config_default, pip_enable);
    mpi_cmd(pinfo->pip_config_default, pip_nums[0]);
    mpi_cmd(pinfo->pip_config_default, pip_nums[1]);
    mpi_cmd(pinfo->pip_config_default, pip_source[0][0]);
    mpi_cmd(pinfo->pip_config_default, pip_source[0][1]);
    mpi_cmd(pinfo->pip_config_default, pip_source[0][2]);
    mpi_cmd(pinfo->pip_config_default, pip_source[0][3]);
    mpi_cmd(pinfo->pip_config_default, pip_source[1][0]);
    mpi_cmd(pinfo->pip_config_default, pip_source[1][1]);
    mpi_cmd(pinfo->pip_config_default, pip_source[1][2]);
    mpi_cmd(pinfo->pip_config_default, pip_source[1][3]);
    mpi_cmd(pinfo->pip_config_default, pip_start_x[0][0]);
    mpi_cmd(pinfo->pip_config_default, pip_start_x[0][1]);
    mpi_cmd(pinfo->pip_config_default, pip_start_x[0][2]);
    mpi_cmd(pinfo->pip_config_default, pip_start_x[0][3]);
    mpi_cmd(pinfo->pip_config_default, pip_start_x[1][0]);
    mpi_cmd(pinfo->pip_config_default, pip_start_x[1][1]);
    mpi_cmd(pinfo->pip_config_default, pip_start_x[1][2]);
    mpi_cmd(pinfo->pip_config_default, pip_start_x[1][3]);
    mpi_cmd(pinfo->pip_config_default, pip_start_y[0][0]);
    mpi_cmd(pinfo->pip_config_default, pip_start_y[0][1]);
    mpi_cmd(pinfo->pip_config_default, pip_start_y[0][2]);
    mpi_cmd(pinfo->pip_config_default, pip_start_y[0][3]);
    mpi_cmd(pinfo->pip_config_default, pip_start_y[1][0]);
    mpi_cmd(pinfo->pip_config_default, pip_start_y[1][1]);
    mpi_cmd(pinfo->pip_config_default, pip_start_y[1][2]);
    mpi_cmd(pinfo->pip_config_default, pip_start_y[1][3]);
    mpi_cmd(pinfo->pip_config_default, pip_width[0][0]);
    mpi_cmd(pinfo->pip_config_default, pip_width[0][1]);
    mpi_cmd(pinfo->pip_config_default, pip_width[0][2]);
    mpi_cmd(pinfo->pip_config_default, pip_width[0][3]);
    mpi_cmd(pinfo->pip_config_default, pip_width[1][0]);
    mpi_cmd(pinfo->pip_config_default, pip_width[1][1]);
    mpi_cmd(pinfo->pip_config_default, pip_width[1][2]);
    mpi_cmd(pinfo->pip_config_default, pip_width[1][3]);
    mpi_cmd(pinfo->pip_config_default, pip_height[0][0]);
    mpi_cmd(pinfo->pip_config_default, pip_height[0][1]);
    mpi_cmd(pinfo->pip_config_default, pip_height[0][2]);
    mpi_cmd(pinfo->pip_config_default, pip_height[0][3]);
    mpi_cmd(pinfo->pip_config_default, pip_height[1][0]);
    mpi_cmd(pinfo->pip_config_default, pip_height[1][1]);
    mpi_cmd(pinfo->pip_config_default, pip_height[1][2]);
    mpi_cmd(pinfo->pip_config_default, pip_height[1][3]);

	mpi_cmd(pinfo->pip_config_default, yuv_type);
	mpi_cmd(pinfo->pip_config_default, rescale_num);
	mpi_cmd(pinfo->pip_config_default, rescale_width[0]);
	mpi_cmd(pinfo->pip_config_default, rescale_height[0]);
	mpi_cmd(pinfo->pip_config_default, rescale_width[1]);
	mpi_cmd(pinfo->pip_config_default, rescale_height[1]);
	mpi_cmd(pinfo->pip_config_default, rescale_width[2]);
	mpi_cmd(pinfo->pip_config_default, rescale_height[2]);
	mpi_cmd(pinfo->pip_config_default, rescale_width[3]);
	mpi_cmd(pinfo->pip_config_default, rescale_height[3]);
	mpi_cmd(pinfo->pip_config_default, rescale_width[4]);
	mpi_cmd(pinfo->pip_config_default, rescale_height[4]);
	mpi_cmd(pinfo->pip_config_default, rescale_width[5]);
	mpi_cmd(pinfo->pip_config_default, rescale_height[5]);
	

    int ret = sgks_mpi_cmd_Send(&pinfo->pip_config_default, sizeof(sgks_dsp_cmd_pip_config_default_s));
    if (ret != SGKS_SUCCESS)
    {
        return ret;
    }
    return SGKS_SUCCESS;


}



static int sgks_mpi_vo_default_img_setup(sgks_vo_dev_info_s *pinfo)
{


    mpi_cmd_hex(pinfo->default_img_setup, cmd_code);
    mpi_cmd(pinfo->default_img_setup, vo_id);
    mpi_cmd(pinfo->default_img_setup, reserved);
    mpi_cmd(pinfo->default_img_setup, default_img_y_addr);
    mpi_cmd(pinfo->default_img_setup, default_img_uv_addr);
    mpi_cmd(pinfo->default_img_setup, default_img_pitch);
    mpi_cmd(pinfo->default_img_setup, default_img_repeat_field);
    mpi_cmd(pinfo->default_img_setup, mjpeg_yuv);
    mpi_cmd(pinfo->default_img_setup, mjpeg_width);
    mpi_cmd(pinfo->default_img_setup, mjpeg_height);
    mpi_cmd_hex(pinfo->default_img_setup, newest_bank_daddr);
    mpi_cmd_hex(pinfo->default_img_setup, bank0_daddr);

    int ret = sgks_mpi_cmd_Send(&pinfo->default_img_setup, sizeof(sgks_dsp_cmd_vo_default_img_setup_s));
    if (ret != SGKS_SUCCESS)
    {
        return ret;
    }
    return SGKS_SUCCESS;

}


static void sgks_mpi_vo_csc_setup(sgks_vo_dev_info_s *pinfo)
{

    mpi_cmd_hex(pinfo->csc_setup, cmd_code);
    mpi_cmd(pinfo->csc_setup, vo_id);
    mpi_cmd(pinfo->csc_setup, csc_type);
    mpi_cmd(pinfo->csc_setup, csc_parms[0]);
    mpi_cmd(pinfo->csc_setup, csc_parms[1]);
    mpi_cmd(pinfo->csc_setup, csc_parms[2]);
    mpi_cmd(pinfo->csc_setup, csc_parms[3]);
    mpi_cmd(pinfo->csc_setup, csc_parms[4]);
    mpi_cmd(pinfo->csc_setup, csc_parms[5]);
    mpi_cmd(pinfo->csc_setup, csc_parms[6]);
    mpi_cmd(pinfo->csc_setup, csc_parms[7]);
    mpi_cmd(pinfo->csc_setup, csc_parms[8]);

    int ret = sgks_mpi_cmd_Send(&pinfo->csc_setup, sizeof(sgks_dsp_cmd_vo_display_csc_setup_s));
    if (ret != SGKS_SUCCESS)
    {
        return ret;
    }
    return SGKS_SUCCESS;

}



static void sgks_mpi_vo_video_setup(sgks_vo_dev_info_s *pinfo)
{

    mpi_cmd_hex(pinfo->video_setup, cmd_code);
    mpi_cmd(pinfo->video_setup, vo_id);
    mpi_cmd(pinfo->video_setup, en);
    mpi_cmd(pinfo->video_setup, src);
    mpi_cmd(pinfo->video_setup, flip);
    mpi_cmd(pinfo->video_setup, rotate);
    mpi_cmd(pinfo->video_setup, win_offset_x);
    mpi_cmd(pinfo->video_setup, win_offset_y);
    mpi_cmd(pinfo->video_setup, win_width);
    mpi_cmd(pinfo->video_setup, win_height);
    mpi_cmd_hex(pinfo->video_setup, default_img_y_addr);
    mpi_cmd_hex(pinfo->video_setup, default_img_uv_addr);
    mpi_cmd(pinfo->video_setup, default_img_pitch);
    mpi_cmd(pinfo->video_setup, default_img_repeat_field);

    int ret = sgks_mpi_cmd_Send(&pinfo->video_setup, sizeof(sgks_dsp_cmd_vo_video_setup_s));
    if (ret != SGKS_SUCCESS)
    {
        return ret;
    }
    return SGKS_SUCCESS;

}


static void sgks_mpi_vo_mixer_setup(sgks_vo_dev_info_s *pinfo)
{

    mpi_cmd_hex(pinfo->mixer_setup, cmd_code);
    mpi_cmd(pinfo->mixer_setup, vo_id);
    mpi_cmd(pinfo->mixer_setup, interlaced);
    mpi_cmd(pinfo->mixer_setup, frm_rate);
    mpi_cmd(pinfo->mixer_setup, act_win_width);
    mpi_cmd(pinfo->mixer_setup, act_win_height);
    mpi_cmd(pinfo->mixer_setup, back_ground_v);
    mpi_cmd(pinfo->mixer_setup, back_ground_u);
    mpi_cmd(pinfo->mixer_setup, back_ground_y);
    mpi_cmd(pinfo->mixer_setup, highlight_v);
    mpi_cmd(pinfo->mixer_setup, highlight_u);
    mpi_cmd(pinfo->mixer_setup, highlight_y);
    mpi_cmd(pinfo->mixer_setup, highlight_thresh);

    int ret = sgks_mpi_cmd_Send(&pinfo->mixer_setup, sizeof(sgks_dsp_cmd_vo_mixer_setup_s));
    if (ret != SGKS_SUCCESS)
    {
        return ret;
    }
    return SGKS_SUCCESS;
}


int sgks_mpi_vo_reset(sgks_vo_dev_info_s *pinfo)
{
    int ret = 0;

    pinfo->reset.reset_mixer = 1;
    pinfo->reset.reset_disp = 1;

    mpi_cmd_hex(pinfo->reset, cmd_code);
    mpi_cmd(pinfo->reset, vo_id);
    mpi_cmd(pinfo->reset, reset_mixer);
    mpi_cmd(pinfo->reset, reset_disp);

    ret = sgks_mpi_cmd_Send(&pinfo->reset, sizeof(sgks_dsp_cmd_vo_reset_s));
    if (ret != SGKS_SUCCESS)
    {
        return ret;
    }

    pinfo->reset.reset_mixer = 0;
    pinfo->reset.reset_disp = 0;

    return SGKS_SUCCESS;
}

int sgks_mpi_vo_Cmd(sgks_mpi_manager_s *mpi,int vo_sw)
{
    int i = 0;

    sgks_vo_dev_info_s *pinfo = NULL;

    for (i=0; i<mpi->mpi_vo_num; i++)
    {

        if(mpi->mpi_vo_dev[i].status == SGKS_VIDEO_SOURCE_STATUS_IDLE)
        {
            Printf("status err! vo id=%d\n",i);
            break;
        }

        if (mpi->mpi_vo_dev[i].vo_user_param.id == SGKS_VOUT_A)
        {
            pinfo = &mpi->mpi_vo_dev[i];
			if(SGKS_VIDEO_VOUT_RESET & vo_sw)
			{
				sgks_mpi_vo_reset(pinfo);
			}
            if(SGKS_VIDEO_VOUT_MIXER & vo_sw)
            {
				sgks_mpi_vo_mixer_setup(pinfo);
			}
            
			if(SGKS_VIDEO_VOUT_SETUP & vo_sw)
            {
				sgks_mpi_vo_video_setup(pinfo);
			}
            
			if(SGKS_VIDEO_VOUT_DISPLAY & vo_sw)
            {
				sgks_mpi_vo_display_setup(pinfo);
			}
            //sgks_mpi_vo_csc_setup(pinfo);
            if(SGKS_VIDEO_VOUT_OSD & vo_sw)
            {
				sgks_mpi_vo_osd_setup(pinfo);
			}            
            //sgks_mpi_vo_osd_clut_setup(pinfo);

            if (pinfo->video_setup.src != SGKS_VO_SRC_ENC)
            {
            	if(SGKS_VIDEO_VOUT_IMG & vo_sw)
	            {
					sgks_mpi_vo_default_img_setup(pinfo);
				}                
            }

            if (mpi->mpi_init_param.dsp_init_param.operation_mode == SGKS_DSP_ENCODE_MODE)
            {					
	            if(SGKS_VIDEO_VOUT_PIP & vo_sw)
	            {
					sgks_mpi_vo_pip_config(pinfo);
				}                
            }

        }

    }




    return SGKS_SUCCESS;


}


int sgks_mpi_vout_Deinit()
{



 return SGKS_SUCCESS;

}


